﻿using AutoMapper;
using QYmall.Core.Common.Emum;
using QYmall.Core.Common.Extensions;
using QYmall.Core.Common.Helper;
using QYmall.Core.DBFactory.Database;
using QYmall.Core.IServices;
using QYmall.Core.Model.Models;
using QYmall.Core.Model.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace QYmall.Core.Services
{
    /// <summary>
    /// 订单发货接口实现
    /// </summary>
    public class OrderInvoiceService : BaseService, IOrderInvoiceService
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public OrderInvoiceService(IDbContextFactory contentFactory,
            IUserService userService, IMapper mapper) : base(contentFactory)
        {
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<OrderInvoice?> QueryAsync(Expression<Func<OrderInvoice, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = await _context.Set<OrderInvoice>()
                .Include(x => x.Express)
                .Include(x => x.InvoiceGoods).ThenInclude(x=>x.OrderGoods)
                .FirstOrDefaultAsync(funcWhere);
            return result;
        }

        /// <summary>
        /// 查询指定数量列表
        /// </summary>
        public async Task<IEnumerable<OrderInvoice>> QueryListAsync(int top, Expression<Func<OrderInvoice, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var result = _context.Set<OrderInvoice>()
                .Include(x => x.Express)
                .Include(x => x.InvoiceGoods).ThenInclude(x=>x.OrderGoods)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类进行排序
            if (top > 0) result = result.Take(top);//等于0显示所有数据
            return await result.ToListAsync();
        }

        /// <summary>
        /// 查询分页列表
        /// </summary>
        public async Task<PaginationList<OrderInvoice>> QueryPageAsync(int pageSize, int pageIndex, Expression<Func<OrderInvoice, bool>> funcWhere,
            string orderBy, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库
            var result = _context.Set<OrderInvoice>()
                .Include(x => x.Express)
                .Include(x => x.InvoiceGoods).ThenInclude(x => x.OrderGoods)
                .Where(funcWhere).OrderByBatch(orderBy);//调用Linq扩展类排序
            return await PaginationList<OrderInvoice>.CreateAsync(pageIndex, pageSize, result);
        }

        /// <summary>
        /// 添加一条记录
        /// </summary>
        public async Task<OrderInvoiceDto> AddAsync(OrderInvoiceEditDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            //获取订单详情
            var orderModel = await _context.Set<Orders>()
                .Include(x => x.OrderGoods)
                .FirstOrDefaultAsync(x => x.Id == modelDto.OrderId);
            if (orderModel == null)
            {
                throw new ResponseException($"订单{modelDto.OrderId}不存在或已删除");
            }
            //检查订单状态
            switch (orderModel.Status)
            {
                case 4:
                    throw new ResponseException("订单已被取消，无法发货");
                case 5:
                    throw new ResponseException("订单已被作废，无法发货");
                case 6:
                    throw new ResponseException("订单已完成，无法发货");
                case 7:
                    throw new ResponseException("订单已全部退款，无法发货");
            }
            //检查发货状态
            if (orderModel.InvoiceStatus == 1)
            {
                throw new ResponseException($"订单{modelDto.OrderId}已全部发货完毕");
            }
            ////检查配送方式
            //var deliveryModel= await _context.Set<ShopDelivery>().FirstOrDefaultAsync(x => x.Id == orderModel.InvoiceDeliveryId);
            //if (deliveryModel == null)
            //{
            //    throw new ResponseException("配送方式不存在或已删除");
            //}
            //检查快递
            if (await _context.Set<ShopExpress>().FirstOrDefaultAsync(x => x.Id == modelDto.ExpressId) == null)
            {
                throw new ResponseException($"快递{modelDto.ExpressId}不存在或已删除");
            }
            //将省市区用逗号连接起来
            modelDto.Address = $"{modelDto.Province},{modelDto.City},{modelDto.Area}," + modelDto.Address;
            
            //映射成实体,获取用户名及发货时间
            var model = _mapper.Map<OrderInvoice>(modelDto);
            model.OrderNo = orderModel.OrderNo;
            model.AddBy = await _userService.GetUserNameAsync();
            model.AddTime = DateTime.Now;

            //修改订单货品为发货状态
            var deliveryGoodsIds = model.InvoiceGoods.Select(x => x.OrderGoodsId);//发货货品的ID集合
            //遍历订单中所有货品，将发货的货品设置为已发货
            foreach (var modelt in orderModel.OrderGoods)
            {
                if (modelt.InvoiceStatus == 0 && deliveryGoodsIds.Contains(modelt.Id))
                {
                    //修改订单货品为发货状态
                    modelt.InvoiceStatus = 1;
                }
            }
            //判断订单中商品货品全部发货或者部分发货
            if (orderModel.OrderGoods.Where(x => x.InvoiceStatus == 0).Count() > 0)
            {
                orderModel.InvoiceStatus = 2;//部分发货
            }
            else
            {
                orderModel.InvoiceStatus = 1;//全部发货
                orderModel.Status = 3;
            }
            orderModel.InvoiceTime = DateTime.Now;

            //修改订单发货状态
            _context.Set<Orders>().Update(orderModel);
            //新增发货记录
            await _context.Set<OrderInvoice>().AddAsync(model);
            //新增订单日志
            await _context.Set<OrderLog>().AddAsync(new OrderLog
            {
                OrderId = orderModel.Id,
                OrderNo = orderModel.OrderNo,
                ActionType = ActionType.Invoice.ToString(),
                AddBy = model.AddBy,
                AddTime = model.AddTime,
                Remark = $"订单[{orderModel.OrderNo}]由[{model.AddBy}]发货"
            });
            //保存到数据库
            var result = await this.SaveAsync();
            if (!result)
            {
                throw new ResponseException("数据保存时发生意外错误");
            }
            //映射成DTO
            return _mapper.Map<OrderInvoiceDto>(model);
        }

        /// <summary>
        /// 根据条件删除记录
        /// </summary>
        public async Task<bool> DeleteAsync(Expression<Func<OrderInvoice, bool>> funcWhere, WriteRoRead writeAndRead = WriteRoRead.Write)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var list = await _context.Set<OrderInvoice>()
                .Include(x => x.InvoiceGoods).Where(funcWhere).ToListAsync();
            if (list == null)
            {
                return false;
            }
            foreach (var modelt in list)
            {
                _context.Set<OrderInvoice>().Attach(modelt);
            }
            _context.Set<OrderInvoice>().RemoveRange(list);
            return await this.SaveAsync();
        }
    }
}
